import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;


public class KeyGen implements Runnable {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		Thread t = new Thread(new KeyGen());
		t.setDaemon(true);
		t.start();
		t = new Thread(new KeyGen());
		t.setDaemon(true);
		t.start();
		
		ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream(args[0]));
		int total = Integer.parseInt(args[1]);
		
		for(int i = 0; i < total; i++) {
			System.out.println(i);
			synchronized(consumer) {
				
				while(length <= 0) {
					try {
						consumer.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				objout.writeObject(keypairs[readindex]);
				readindex++;
				readindex %= keypairs.length;
				
				synchronized(producer) {
					length--;
					producer.notify();
				}
			}
		}
		objout.close();
	}
	
	public void run() {
		
		KeyPairGenerator keygen = null;
		try {
			keygen = KeyPairGenerator.getInstance("RSA");
		} catch (NoSuchAlgorithmException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		keygen.initialize(2048);
		KeyPair pair;
		while(true) {
			pair = keygen.generateKeyPair();
			
			synchronized(producer) {
				while(length >= keypairs.length) {
					try {
						producer.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				keypairs[writeindex] = pair;
				writeindex++;
				writeindex %= keypairs.length;
				
				synchronized(consumer) {
					length++;
					consumer.notify();
				}
			}
		}
	}
	
	public static Object producer = new Object();
	public static Object consumer = new Object();
	public static KeyPair[] keypairs = new KeyPair[10];
	public static int readindex = 0;
	public static int writeindex = 0;
	public static int length = 0;

}
